home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet multimedia / Animacje, filmy i prezentacje / Modelowanie 3D / K-3D 0.6.5.0 / k3d-all-in-one-setup-0.6.5.0.exe / aqsis-setup-1.1.0-2006-12-09.exe / include / aqsis / vector4d.h < prev   
Encoding:
C/C++ Source or Header  |  2006-06-14  |  12.0 KB  |  517 lines

  1. // Aqsis
  2. // Copyright ⌐ 1997 - 2001, Paul C. Gregory
  3. //
  4. // Contact: pgregory@aqsis.org
  5. //
  6. // This library is free software; you can redistribute it and/or
  7. // modify it under the terms of the GNU General Public
  8. // License as published by the Free Software Foundation; either
  9. // version 2 of the License, or (at your option) any later version.
  10. //
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14. // General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU General Public
  17. // License along with this library; if not, write to the Free Software
  18. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  
  20.  
  21. /** \file
  22.         \brief Declares the CqVector4D class which encapsulates a homogenous 4D vector.
  23.         \author Paul C. Gregory (pgregory@aqsis.org)
  24. */
  25.  
  26. //? Is .h included already?
  27. #ifndef VECTOR4D_H_INCLUDED
  28. #define VECTOR4D_H_INCLUDED 1
  29.  
  30. #include    <iostream>
  31.  
  32. #include    "aqsis.h"
  33. #include    "vector3d.h"
  34.  
  35. START_NAMESPACE( Aqsis )
  36.  
  37. //-----------------------------------------------------------------------
  38.  
  39. class CqVector3D;
  40.  
  41. //----------------------------------------------------------------------
  42. /** \class CqVector4D
  43.  * \brief Define class structure for 4D homogeneous vector.
  44.  */
  45.  
  46. class CqVector4D
  47. {
  48.     public:
  49.         CqVector4D() : m_x( 0.0f ), m_y( 0.0f ), m_z( 0.0f ), m_h( 1.0f )
  50.         {}
  51.         CqVector4D( TqFloat x, TqFloat y, TqFloat z, TqFloat h = 1.0f ) : m_x( x ), m_y( y ), m_z( z ), m_h( h )
  52.         {}
  53.         CqVector4D( const CqVector3D &From );
  54.         CqVector4D( const TqFloat Array[ 4 ] ) : m_x( Array[ 0 ] ), m_y( Array[ 1 ] ), m_z( Array[ 2 ] ), m_h( Array[ 3 ] )
  55.         {}
  56.         ~CqVector4D()
  57.         {}
  58.  
  59.         /** Get the x component.
  60.          */
  61.         TqFloat    x() const
  62.         {
  63.             return ( m_x );
  64.         }
  65.         /** Set the x component.
  66.          */
  67.         void    x( TqFloat x )
  68.         {
  69.             m_x = x;
  70.         }
  71.         /** Get the y component.
  72.          */
  73.         TqFloat    y() const
  74.         {
  75.             return ( m_y );
  76.         }
  77.         /** Set the y component.
  78.          */
  79.         void    y( TqFloat y )
  80.         {
  81.             m_y = y;
  82.         }
  83.         /** Get the z component.
  84.          */
  85.         TqFloat    z() const
  86.         {
  87.             return ( m_z );
  88.         }
  89.         /** Set the z component.
  90.          */
  91.         void    z( TqFloat z )
  92.         {
  93.             m_z = z;
  94.         }
  95.         /** Get the h component.
  96.          */
  97.         TqFloat    h() const
  98.         {
  99.             return ( m_h );
  100.         }
  101.         /** Set the h component.
  102.          */
  103.         void    h( TqFloat h )
  104.         {
  105.             m_h = h;
  106.         }
  107.  
  108.         /** Array based component access.
  109.          * \param i Integer component index, 0-3.
  110.          * \return Appropriate component, or h if index is invalid.
  111.          */
  112.         TqFloat&    operator[] ( TqInt i )
  113.         {
  114.             switch ( i )
  115.             {
  116.                 case 0:
  117.                     return ( m_x );
  118.                     break;
  119.                 case 1:
  120.                     return ( m_y );
  121.                     break;
  122.                 case 2:
  123.                     return ( m_z );
  124.                     break;
  125.                 case 3:
  126.                     return ( m_h );
  127.                     break;
  128.                 default:
  129.                     break;
  130.             }
  131.             return ( m_h );
  132.         }
  133.  
  134.         /** Array based component access.
  135.          * \param i Integer component index, 0-3.
  136.          * \return Appropriate component, or h if index is invalid.
  137.          */
  138.         const TqFloat&    operator[] ( TqInt i ) const
  139.         {
  140.             switch ( i )
  141.             {
  142.                 case 0:
  143.                     return ( m_x );
  144.                     break;
  145.                 case 1:
  146.                     return ( m_y );
  147.                     break;
  148.                 case 2:
  149.                     return ( m_z );
  150.                     break;
  151.                 case 3:
  152.                     return ( m_h );
  153.                     break;
  154.                 default:
  155.                     break;
  156.             }
  157.             return ( m_h );
  158.         }
  159.  
  160.         /** Get the length squared.
  161.          */
  162.         TqFloat    Magnitude2() const;
  163.         /** Get the length.
  164.          */
  165.         TqFloat    Magnitude() const;
  166.  
  167.         void    Unit()
  168.         {
  169.             m_h = ( Magnitude() );
  170.         }
  171.         void    Homogenize()
  172.         {
  173.             if ( m_h != 1.0 )
  174.             {
  175.                 m_x /= m_h;
  176.                 m_y /= m_h;
  177.                 m_z /= m_h;
  178.                 m_h = 1.0;
  179.             }
  180.         }
  181.  
  182.         CqVector4D& operator= ( const CqVector3D &From );
  183.         CqVector4D& operator+=( const CqVector4D &From );
  184.         CqVector4D& operator-=( const CqVector4D &From );
  185.         CqVector4D& operator%=( const CqVector4D &From );
  186.         CqVector4D& operator*=( const TqFloat Scale );
  187.         CqVector4D& operator/=( const TqFloat Scale );
  188.         TqBool    operator==( const CqVector4D &Cmp ) const;
  189.         TqBool    operator!=( const CqVector4D &Cmp ) const;
  190.         TqBool    operator>=( const CqVector4D &Cmp ) const;
  191.         TqBool    operator<=( const CqVector4D &Cmp ) const;
  192.         TqBool    operator>( const CqVector4D &Cmp ) const;
  193.         TqBool    operator<( const CqVector4D &Cmp ) const;
  194.  
  195.         friend CqVector4D    operator*( const TqFloat f, const CqVector4D& v )
  196.         {
  197.             CqVector4D r( v );
  198.             return ( r *= f );
  199.         }
  200.         friend CqVector4D    operator*( const CqVector4D& v, const TqFloat f )
  201.         {
  202.             CqVector4D r( v );
  203.             return ( r *= f );
  204.         }
  205.         friend CqVector4D    operator/( const TqFloat f, const CqVector4D& v )
  206.         {
  207.             CqVector4D r( v );
  208.             return ( r /= f );
  209.         }
  210.         friend CqVector4D    operator/( const CqVector4D& v, const TqFloat f )
  211.         {
  212.             CqVector4D r( v );
  213.             return ( r /= f );
  214.         }
  215.  
  216.         friend CqVector4D    operator+( const CqVector4D& a, const CqVector4D& b )
  217.         {
  218.             CqVector4D r( a );
  219.             return ( r += b );
  220.         }
  221.         friend CqVector4D    operator-( const CqVector4D& a, const CqVector4D& b )
  222.         {
  223.             CqVector4D r( a );
  224.             return ( r -= b );
  225.         }
  226.         friend CqVector4D    operator-( const CqVector4D& v )
  227.         {
  228.             return ( CqVector4D( -v.m_x, -v.m_y, -v.m_z, v.m_h ) );
  229.         } // Negation
  230.  
  231.         friend TqFloat    operator*( const CqVector4D& a, const CqVector4D& b );
  232.         friend CqVector4D    operator%( const CqVector4D& a, const CqVector4D& b );    // X product
  233.         friend std::ostream &operator<<( std::ostream &Stream, const CqVector4D &Vector );
  234.  
  235.     protected:
  236.         TqFloat    m_x;    ///< X component.
  237.         TqFloat    m_y;    ///< Y component.
  238.         TqFloat    m_z;    ///< Z component.
  239.         TqFloat    m_h;    ///< H component.
  240. }
  241. ;
  242.  
  243. //-----------------------------------------------------------------------
  244.  
  245. //---------------------------------------------------------------------
  246. /** Copy constructor from 3D Vector.
  247.  */
  248.  
  249. inline CqVector4D::CqVector4D( const CqVector3D &From )
  250. {
  251.     *this = From;
  252. }
  253.  
  254. //---------------------------------------------------------------------
  255. /** Return magnitude squared of this vector.
  256.  */
  257.  
  258. inline TqFloat CqVector4D::Magnitude2() const
  259. {
  260.     if ( m_h == 1.0 )
  261.         return ( ( m_x * m_x ) + ( m_y * m_y ) + ( m_z * m_z ) );
  262.     else
  263.         return ( ( ( m_x * m_x ) + ( m_y * m_y ) + ( m_z * m_z ) ) / ( m_h * m_h ) );
  264. }
  265.  
  266. //---------------------------------------------------------------------
  267. /** Return magnitude of this vector.
  268.  */
  269.  
  270. inline TqFloat CqVector4D::Magnitude() const
  271. {
  272.     return ( sqrt( Magnitude2() ) );
  273. }
  274.  
  275.  
  276. //---------------------------------------------------------------------
  277. /** Add a vector to this vector.
  278.  */
  279.  
  280. inline CqVector4D &CqVector4D::operator+=( const CqVector4D &From )
  281. {
  282.     TqFloat Hom = m_h / From.m_h;
  283.  
  284.     m_x += From.m_x * Hom;
  285.     m_y += From.m_y * Hom;
  286.     m_z += From.m_z * Hom;
  287.  
  288.     return ( *this );
  289. }
  290.  
  291.  
  292.  
  293. //---------------------------------------------------------------------
  294. /** Subtract a vector from this vector.
  295.  */
  296.  
  297. inline CqVector4D &CqVector4D::operator-=( const CqVector4D &From )
  298. {
  299.     TqFloat Hom = m_h / From.m_h;
  300.  
  301.     m_x -= From.m_x * Hom;
  302.     m_y -= From.m_y * Hom;
  303.     m_z -= From.m_z * Hom;
  304.  
  305.     return ( *this );
  306. }
  307.  
  308. //---------------------------------------------------------------------
  309. /** Dot product of two vectors.
  310.  */
  311.  
  312. inline TqFloat operator*( const CqVector4D &a, const CqVector4D &From )
  313. {
  314.     CqVector4D    A( a );
  315.     CqVector4D    B( From );
  316.  
  317.     A.Homogenize();
  318.     B.Homogenize();
  319.  
  320.     return ( ( A.m_x * B.m_x ) +
  321.              ( A.m_y * B.m_y ) +
  322.              ( A.m_z * B.m_z ) );
  323. }
  324.  
  325.  
  326. //---------------------------------------------------------------------
  327. /** Cross product of two vectors.
  328.  */
  329.  
  330. inline CqVector4D operator%( const CqVector4D &a, const CqVector4D &From )
  331. {
  332.     CqVector4D Temp( a );
  333.     Temp %= From;
  334.     return ( Temp );
  335. }
  336.  
  337.  
  338. //---------------------------------------------------------------------
  339. /** Sets this vector to be the cross product of itself and another vector.
  340.  */
  341.  
  342. inline CqVector4D &CqVector4D::operator%=( const CqVector4D &From )
  343. {
  344.     CqVector4D    A( *this );
  345.     CqVector4D    B( From );
  346.  
  347.     A.Homogenize();
  348.     B.Homogenize();
  349.  
  350.     m_x = ( A.m_y * B.m_z ) - ( A.m_z * B.m_y );
  351.     m_y = ( A.m_z * B.m_x ) - ( A.m_x * B.m_z );
  352.     m_z = ( A.m_x * B.m_y ) - ( A.m_y * B.m_x );
  353.  
  354.     return ( *this );
  355. }
  356.  
  357.  
  358. //---------------------------------------------------------------------
  359. /** Copy from specified 3D vector.
  360.  */
  361.  
  362. inline CqVector4D &CqVector4D::operator=( const CqVector3D &From )
  363. {
  364.     m_x = From.x();
  365.     m_y = From.y();
  366.     m_z = From.z();
  367.     m_h = 1.0;
  368.  
  369.     return ( *this );
  370. }
  371.  
  372.  
  373. //---------------------------------------------------------------------
  374. /** Scale this vector by the specifed scale factor.
  375.  */
  376.  
  377. inline CqVector4D &CqVector4D::operator*=( const TqFloat Scale )
  378. {
  379.     /*    if(Scale != 0.0)
  380.         {
  381.             m_h /= Scale;
  382.         }
  383.         else
  384.         {
  385.             m_x = m_y = m_z = 0.0;
  386.         }
  387.     */
  388.  
  389.     m_x *= Scale;
  390.     m_z *= Scale;
  391.     m_y *= Scale;
  392.  
  393.     return ( *this );
  394. }
  395.  
  396.  
  397.  
  398. //---------------------------------------------------------------------
  399. /** Divide this vector by the specifed scale factor.
  400.  */
  401.  
  402. inline CqVector4D &CqVector4D::operator/=( const TqFloat Scale )
  403. {
  404.     m_h *= Scale;
  405.  
  406.     return ( *this );
  407. }
  408.  
  409.  
  410. //---------------------------------------------------------------------
  411. /** Compare two vectors for equality.
  412.  */
  413.  
  414. inline TqBool CqVector4D::operator==( const CqVector4D &Cmp ) const
  415. {
  416.     /*    TqFloat Hom = m_h / Cmp.m_h;
  417.      
  418.         return ( ( m_x == ( Cmp.m_x * Hom ) ) &&
  419.                  ( m_y == ( Cmp.m_y * Hom ) ) &&
  420.                  ( m_z == ( Cmp.m_z * Hom ) ) );
  421.     */
  422.  
  423.     // exact equality of floats isn't actually very useful because of slight
  424.     // differences due to rounding errors. a fuzzy compare is generally more useful.
  425.     // if the vectors have different h values the above is unlikely to
  426.     // return true, so we might as well just test for exact equality of each component.
  427.     return ((m_x == Cmp.m_x) &&
  428.             (m_y == Cmp.m_y) &&
  429.             (m_z == Cmp.m_z) &&
  430.             (m_h == Cmp.m_h));
  431. }
  432.  
  433.  
  434. //---------------------------------------------------------------------
  435. /** Compare two vectors for inequality.
  436.  */
  437.  
  438. inline TqBool CqVector4D::operator!=( const CqVector4D &Cmp ) const
  439. {
  440.     return ( !( *this == Cmp ) );
  441. }
  442.  
  443.  
  444. //---------------------------------------------------------------------
  445. /** Compare two vectors for greater than or equal.
  446.  */
  447.  
  448. inline TqBool CqVector4D::operator>=( const CqVector4D &Cmp ) const
  449. {
  450.     TqFloat Hom = m_h / Cmp.m_h;
  451.  
  452.     return ( ( m_x >= ( Cmp.m_x * Hom ) ) &&
  453.              ( m_y >= ( Cmp.m_y * Hom ) ) &&
  454.              ( m_z >= ( Cmp.m_z * Hom ) ) );
  455. }
  456.  
  457.  
  458. //---------------------------------------------------------------------
  459. /** Compare two vectors for less than or equal.
  460.  */
  461.  
  462. inline TqBool CqVector4D::operator<=( const CqVector4D &Cmp ) const
  463. {
  464.     TqFloat Hom = m_h / Cmp.m_h;
  465.  
  466.     return ( ( m_x <= ( Cmp.m_x * Hom ) ) &&
  467.              ( m_y <= ( Cmp.m_y * Hom ) ) &&
  468.              ( m_z <= ( Cmp.m_z * Hom ) ) );
  469. }
  470.  
  471.  
  472. //---------------------------------------------------------------------
  473. /** Compare two vectors for greater than.
  474.  */
  475.  
  476. inline TqBool CqVector4D::operator>( const CqVector4D &Cmp ) const
  477. {
  478.     TqFloat Hom = m_h / Cmp.m_h;
  479.  
  480.     return ( ( m_x > ( Cmp.m_x * Hom ) ) &&
  481.              ( m_y > ( Cmp.m_y * Hom ) ) &&
  482.              ( m_z > ( Cmp.m_z * Hom ) ) );
  483. }
  484.  
  485.  
  486. //---------------------------------------------------------------------
  487. /** Compare two vectors for less than.
  488.  */
  489.  
  490. inline TqBool CqVector4D::operator<( const CqVector4D &Cmp ) const
  491. {
  492.     TqFloat Hom = m_h / Cmp.m_h;
  493.  
  494.     return ( ( m_x < ( Cmp.m_x * Hom ) ) &&
  495.              ( m_y < ( Cmp.m_y * Hom ) ) &&
  496.              ( m_z < ( Cmp.m_z * Hom ) ) );
  497. }
  498.  
  499.  
  500. //----------------------------------------------------------------------
  501. /** Outputs a vector to an output stream.
  502.  * \param Stream Stream to output the matrix to.
  503.  * \param Vector The vector to output.
  504.  * \return The new state of Stream.
  505.  */
  506.  
  507. inline std::ostream &operator<<( std::ostream &Stream, const CqVector4D &Vector )
  508. {
  509.     Stream << Vector.m_x << "," << Vector.m_y << "," << Vector.m_z << "," << Vector.m_h;
  510.     return ( Stream );
  511. }
  512.  
  513.  
  514. END_NAMESPACE( Aqsis )
  515.  
  516. #endif    // !VECTOR4D_H_INCLUDED
  517.